package com.iplant.mes.serviceImpl;

import com.iplant.ams.service.po.dms.fault.DMSFaultBase;
import com.iplant.aps.service.po.aps.APSTaskPartPoint;
import com.iplant.aps.service.po.aps.APSTaskPartPointDay;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.basic.service.basicenum.bpm.BPMEventModule;
import com.iplant.basic.service.basicenum.bpm.TaskQueryType;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.utils.Constants;
import com.iplant.mes.service.NCRService;
import com.iplant.mes.service.mesenum.exc.EXCUnusualStatus;
import com.iplant.mes.service.po.exc.*;
import com.iplant.mes.service.po.ncr.NCRTask;
import com.iplant.mes.service.po.sfc.SFCWorkpieceRecord;
import com.iplant.mes.service.po.sfc.SFCWorkpieceResume;
import com.iplant.mes.serviceImpl.dao.ncr.NCRTaskDAO;
import com.iplant.pdm.service.po.bop.FPCRoutePartPoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class NCRServiceImpl implements NCRService {

    //region 构造函数
    public NCRServiceImpl() {
        Constants.BPMServiceMap.put(BPMEventModule.NCR, this);
    }
    //endregion

    //region 单实例

    private static NCRService Instance = null;

    public static NCRService getInstance() {
        if (Instance == null)
            Instance = new NCRServiceImpl();

        return Instance;
    }
    //endregion

    //region POService
    PoService<DMSFaultBase> mDMSFaultBaseService = ORMUtils.GetPoService(DMSFaultBase.class);
    PoService<EXCLineStop> mEXCLineStopService = ORMUtils.GetPoService(EXCLineStop.class);
    PoService<APSTaskPartPoint> mAPSTaskPartPointService = ORMUtils.GetPoService(APSTaskPartPoint.class);
    PoService<EXCProductRepair> mEXCProductRepairService = ORMUtils.GetPoService(EXCProductRepair.class);
    PoService<EXCProductRepairItem> mEXCProductRepairItemService = ORMUtils.GetPoService(EXCProductRepairItem.class);
    PoService<APSTaskPartPointDay> mAPSTaskPartPointDayService = ORMUtils.GetPoService(APSTaskPartPointDay.class);
    PoService<SFCWorkpieceResume> mSFCWorkpieceResumeService = ORMUtils.GetPoService(SFCWorkpieceResume.class);
    PoService<FPCRoutePartPoint> mFPCRoutePartPointService = ORMUtils.GetPoService(FPCRoutePartPoint.class);
    PoService<SFCWorkpieceRecord> mSFCWorkpieceRecordService = ORMUtils.GetPoService(SFCWorkpieceRecord.class);
    PoService<NCRTask> mNCRTaskService = ORMUtils.GetPoService(NCRTask.class);
    //endregion

    //region 不合格评审流程
    @Override
    public ServiceResult<NCRTask> BPM_QueryDefaultTask(BMSEmployee wLoginUser,
                                                       int wTaskID, int wEventID) {
        ServiceResult<NCRTask> wResult = new ServiceResult<>();
        wResult.Result = new NCRTask();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);


            Map<String, Object> wParams = new HashMap<String, Object>();

            wParams.put("UpFlowID", wLoginUser.ID);
            wParams.put("Status", "0");

            NCRTask wNCRTask = mNCRTaskService.SelectPO(wLoginUser, wParams,
                    wErrorCode);
            if (wNCRTask != null && wNCRTask.ID > 0) {
                wNCRTask.FlowType = wEventID;
                wNCRTask.UpFlowID = wLoginUser.ID;
                wNCRTask.UpFlowName = wLoginUser.Name;
                wNCRTask.CreateTime = Calendar.getInstance();
                wNCRTask.EditTime = Calendar.getInstance();

                wResult.Result = wNCRTask;
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<NCRTask> BPM_CreateTask(BMSEmployee wLoginUser,
                                                 BPMEventModule wEventID) {
        ServiceResult<NCRTask> wResult = new ServiceResult<>();
        wResult.Result = new NCRTask();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            NCRTask wPo = new NCRTask();
            wPo.setUserInfo(wLoginUser);
            wPo.ID = 0;
            wPo.FlowType = wEventID.getValue();
            wPo.UpFlowID = wLoginUser.ID;
            wPo.UpFlowName = wLoginUser.Name;
            wPo.Status = 0;
            wPo.StatusText = "";
            wPo.CreateTime = Calendar.getInstance();
            wPo.EditTime = Calendar.getInstance();

            mNCRTaskService.UpdatePo(wLoginUser, wPo, wErrorCode);

            wResult.Result = wPo;

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<NCRTask> BPM_SubmitTask(BMSEmployee wLoginUser,
                                                 NCRTask wData) {
        ServiceResult<NCRTask> wResult = new ServiceResult<>();
        wResult.Result = wData;
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wData.Status == EXCUnusualStatus.Confirm.getValue()) {
                wData.StatusText = EXCUnusualStatus.Confirm.getLabel();
            }

            wData.setUserInfo(wLoginUser);
            wData.EditTime = Calendar.getInstance();
            mNCRTaskService.UpdatePo(wLoginUser, wData, wErrorCode);

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<NCRTask> BPM_GetTask(BMSEmployee wLoginUser, int wID) {
        ServiceResult<NCRTask> wResult = new ServiceResult<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);

        Map<String, Object> wParams = new HashMap<String, Object>();
        wParams.put("ID", wID);
        wResult.Result = mNCRTaskService.SelectPO(wLoginUser, wParams,
                wErrorCode);
        wResult.AddFaultCode(wErrorCode);
        return wResult;
    }

    @Override
    public ServiceResult<List<NCRTask>> BPM_QueryEmployeeAllWeb(BMSEmployee wLoginUser, Map<String, Object> wParams,
                                                                Pagination wPagination) {
        ServiceResult<List<NCRTask>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            int wStatus = StringUtils.parseInt(wParams.get("Status"));
            switch (wStatus) {
                case 0://待办
                    wParams.remove("CStartTime");
                    wParams.remove("CEndTime");
                    wParams.remove("DStartTime");
                    wParams.remove("DEndTime");
                    wParams.put("Status", "1,2,3,4,5,6,7,8,9,10,11");
                    wResult.Result = NCRTaskDAO.getInstance().SelectPOList(wLoginUser, wParams, wPagination,
                            wErrorCode);
                    break;
                case 1://已办
                    wParams.put("Status", "20,21,22");
                    wResult.Result = NCRTaskDAO.getInstance().SelectPOList(wLoginUser, wParams, wPagination,
                            wErrorCode);
                    break;
                default://全部
                    wParams.put("Status", "1,2,3,4,5,6,7,8,9,10,11,20,21,22");
                    wResult.Result = NCRTaskDAO.getInstance().SelectPOList(wLoginUser, wParams, wPagination,
                            wErrorCode);
                    break;
            }

            if (wResult.Result.size() == 0 || wStatus == 1) {
                return wResult;
            }

            // 待办数据处理
            List<NCRTask> wBaseList =
                    NCRTaskDAO.getInstance().BFC_GetUndoTaskList(wLoginUser,
                            wLoginUser.ID,
                            new ArrayList<>(Collections.singletonList(BPMEventModule.NCR.getValue()))
                            , wParams, Pagination.getNewMaxSize(), wErrorCode);
            if (wBaseList == null || wBaseList.size() == 0) {
                return wResult;
            }
            for (NCRTask wTaskBase : wBaseList) {
                wTaskBase.TagTypes = TaskQueryType.ToHandle.getValue();
                for (int i = 0; i < wResult.Result.size(); i++) {
                    if (wResult.Result.get(i).ID == wTaskBase.ID)
                        wResult.Result.set(i, wTaskBase);
                }
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    @Override
    public Class<NCRTask> GetTClass() {
        return NCRTask.class;
    }
    //endregion

}
